home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XA_6S.ZIP / SOURCE / RECTLIST.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-13  |  7.4 KB  |  303 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <VDI.H>
  9. #include <MINTBIND.H>
  10. #include <memory.h>
  11. #include "XA_DEFS.H"
  12. #include "XA_TYPES.H"
  13. #include "XA_GLOBL.H"
  14. #include "K_DEFS.H"
  15. #include "C_WINDOW.H"
  16. #include "EVENTS.H"
  17. #include "rectlist.h"
  18.  
  19. #define max(x,y)    (((x)>(y))?(x):(y))
  20. #define min(x,y)    (((x)<(y))?(x):(y))
  21. /*
  22.  *    Compute intersection of two rectangles; put result rectangle
  23.  *    into *d; return TRUE if intersection is nonzero.
  24.  *
  25.  *    (Original version of this function taken from Digital Research's
  26.  *    GEM sample application `DEMO' [aka `DOODLE'],  Version 1.1,
  27.  *    March 22, 1985)
  28.  */
  29. short rc_intersect(const GRECT *s, GRECT *d)
  30. {
  31.     short x1,y1,x2,y2 ;
  32.  
  33.     x1 = max( s->g_x, d->g_x ) ;
  34.     y1 = max( s->g_y, d->g_y ) ;
  35.     x2 = min( s->g_x+s->g_w, d->g_x+d->g_w ) ;
  36.     y2 = min( s->g_y+s->g_h, d->g_y+d->g_h ) ;
  37.     d->g_x = x1 ;
  38.     d->g_y = y1 ;
  39.     d->g_w = x2 - x1 ;
  40.     d->g_h = y2 - y1 ;
  41.     return (x2 > x1) && (y2 > y1) ;
  42. }
  43.  
  44. /*
  45.     Rectangle List Generator 
  46.     - generates a list of clipping rectangles for a given window.
  47.     (Not a routine I'm proud of I'm afraid, but it seems to work ok)
  48.     ++cg[29/9/96]: as I've not managed to debug Johan's rect list stuff,
  49.     here's a mod to my original algorithm that only does a single malloc....
  50. */
  51.  
  52. XA_RECT_LIST *generate_rect_list(XA_WINDOW *w)
  53. {
  54.     XA_WINDOW *wl;
  55.     XA_RECT_LIST *rl,*rlist,*nrl,*cnrl,*rl_next;
  56.     XA_RECT_LIST *free_list;
  57.     GRECT r_ours,r_win;
  58.     short win_cnt,f;
  59.  
  60.     DIAGS(("GenRectList:wind=%d\n",w->handle));
  61.  
  62.     if (w->rect_start)
  63.     {
  64.         DIAGS(("free existing list\n"));
  65.         free(w->rect_start);
  66.     }
  67.  
  68.     win_cnt=0;    
  69.     for(wl=w->prev; wl; wl=wl->prev)
  70.         win_cnt++;        
  71.  
  72.     DIAGS(("win_cnt=%d,allocate %d entries\n",win_cnt,win_cnt*6+2));
  73.  
  74. /* Block allocate the required space (approximately) */    
  75.     w->rect_start=rlist=(XA_RECT_LIST*)malloc(sizeof(XA_RECT_LIST)*(win_cnt*6+2));
  76.     rlist++;
  77.     rlist->x=w->x;
  78.     rlist->y=w->y;
  79.     rlist->w=w->w;
  80.     rlist->h=w->h;
  81.     rlist->next=NULL;
  82.  
  83.     if (win_cnt)
  84.     {
  85.         DIAGS(("initialising free_list\n"));
  86.         rl=free_list=rlist+1;
  87.         for(f=0; f<win_cnt*6; f++)
  88.         {
  89.             DIAGS(("%d\n",f));
  90.             free_list[f].next=&free_list[f+1];
  91.         }
  92.         free_list[win_cnt*6-1].next=NULL;
  93.     
  94.         Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  95.     
  96.         wl=w->prev;
  97.         while(wl)
  98.         {
  99.             if (wl->is_open)
  100.             {
  101.                 DIAGS(("Do Window %d @(%d,%d,%d,%d)\n",wl->handle,wl->x,wl->y,wl->w,wl->h));
  102.                 nrl=NULL;
  103.                 for(rl=rlist; rl; rl=rl_next)
  104.                 {
  105.                     DIAGS((" rl=[%d,%d,%d,%d]:",rl->x,rl->y,rl->w,rl->h));
  106.                     if (nrl)
  107.                     {
  108.                         DIAGS((" nrl=[%d,%d,%d,%d]\n",nrl->x,nrl->y,nrl->w,nrl->h));
  109.                     }else{
  110.                         DIAGS((" nrl=NULL\n"));
  111.                     }
  112.                         
  113.                     r_win.g_x=wl->x;
  114.                     r_win.g_y=wl->y;
  115.                     r_win.g_w=wl->w;
  116.                     r_win.g_h=wl->h;
  117.         
  118.                     r_ours.g_x=rl->x;
  119.                     r_ours.g_y=rl->y;
  120.                     r_ours.g_w=rl->w;
  121.                     r_ours.g_h=rl->h;
  122.                 
  123.                     if(rc_intersect(&r_ours, &r_win))    /* if window intersects this rectangle, process */
  124.                     {
  125.                         DIAGS((" intersect=[%d,%d,%d,%d]\n",r_win.g_x,r_win.g_y,r_win.g_w,r_win.g_h));
  126.                 
  127.         /* If window doesn't completely mask this rectangle, create new results */                
  128.                         if((r_ours.g_w!=r_win.g_w)||(r_ours.g_h!=r_win.g_h))
  129.                         {
  130.                             if(r_win.g_x!=r_ours.g_x)
  131.                             {
  132.                                 cnrl=free_list; free_list=free_list->next;
  133.                                 cnrl->x=r_ours.g_x;
  134.                                 cnrl->y=r_ours.g_y;
  135.                                 cnrl->w=r_win.g_x-r_ours.g_x;
  136.                                 cnrl->h=r_ours.g_h;
  137.                                 cnrl->next=nrl;
  138.                                 DIAGS(("  Add_ra=[%d,%d,%d,%d]\n",cnrl->x,cnrl->y,cnrl->w,cnrl->h));
  139.                                 nrl=cnrl;
  140.                             }
  141.                             if(r_win.g_x+r_win.g_w!=r_ours.g_x+r_ours.g_w)
  142.                             {
  143.                                 cnrl=free_list; free_list=free_list->next;
  144.                                 cnrl->x=r_win.g_x+r_win.g_w;
  145.                                 cnrl->y=r_ours.g_y;
  146.                                 cnrl->w=r_ours.g_x+r_ours.g_w-r_win.g_x-r_win.g_w;
  147.                                 cnrl->h=r_ours.g_h;
  148.                                 cnrl->next=nrl;
  149.                                 DIAGS(("  Add_rb=[%d,%d,%d,%d]\n",cnrl->x,cnrl->y,cnrl->w,cnrl->h));
  150.                                 nrl=cnrl;
  151.                             }
  152.                             if(r_win.g_y!=r_ours.g_y)
  153.                             {
  154.                                 cnrl=free_list; free_list=free_list->next;
  155.                                 cnrl->x=r_win.g_x;
  156.                                 cnrl->y=r_ours.g_y;
  157.                                 cnrl->w=r_win.g_w;
  158.                                 cnrl->h=r_win.g_y-r_ours.g_y;
  159.                                 cnrl->next=nrl;
  160.                                 DIAGS(("  Add_rc=[%d,%d,%d,%d]\n",cnrl->x,cnrl->y,cnrl->w,cnrl->h));
  161.                                 nrl=cnrl;
  162.                             }
  163.                             if(r_win.g_y+r_win.g_h!=r_ours.g_y+r_ours.g_h)
  164.                             {
  165.                                 cnrl=free_list; free_list=free_list->next;
  166.                                 cnrl->x=r_win.g_x;
  167.                                 cnrl->y=r_win.g_y+r_win.g_h;
  168.                                 cnrl->w=r_win.g_w;
  169.                                 cnrl->h=r_ours.g_y+r_ours.g_h-r_win.g_y-r_win.g_h;
  170.                                 cnrl->next=nrl;
  171.                                 DIAGS(("  Add_rd=[%d,%d,%d,%d]\n",cnrl->x,cnrl->y,cnrl->w,cnrl->h));
  172.                                 nrl=cnrl;
  173.                             }
  174.                         }else{
  175.                             DIAGS(("  Obscured - freeing\n"));
  176.                         }
  177.                         rl_next=rl->next;            /* release the original rectangle */
  178.                         rl->next=free_list;        /* add original rectangle to the free list */
  179.                         free_list=rl;
  180.                     }else{    /* Keep the current rectangle, it hasn't been changed */
  181.                         DIAGS(("  Disjoint - keeping\n"));
  182.                         rl_next=rl->next;
  183.                         rl->next=nrl;
  184.                         nrl=rl;
  185.                     }
  186.                 }
  187.                 rlist=nrl;
  188.             }
  189.             wl=wl->prev;
  190.         }
  191.  
  192.         Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  193.     }
  194.     
  195.     w->rect_list=w->rect_user=w->rect_start;
  196.     
  197.     if (rlist)
  198.     {
  199.         *(w->rect_start)=*rlist;
  200.     }else{
  201.         free(w->rect_start);
  202.         w->rect_list=w->rect_user=w->rect_start=NULL;
  203.     }    
  204.  
  205. #if GENERATE_DIAGS        
  206.     DIAGS(("rect_list dump:\n"));
  207.     for(rlist=w->rect_start; rlist; rlist=rlist->next)
  208.         DIAGS(("{[%d,%d,%d,%d]@%lx,next=%lx}\n",rlist->x,rlist->y,rlist->w,rlist->h,rlist,rlist->next));
  209. #endif
  210.     
  211.     
  212.     return w->rect_start;
  213. }
  214.  
  215. void dispose_rect_list(XA_WINDOW *w)
  216. {
  217.     if (w->rect_start)
  218.     {
  219.         DIAGS(("free rect list\n"));
  220.         free(w->rect_start);
  221.     }
  222.     w->rect_start=w->rect_user=w->rect_list=NULL;
  223. }
  224.  
  225.  
  226. XA_RECT_LIST *rect_get_user_first(XA_WINDOW *w)
  227. {
  228.     DIAGS(("get_user_first(%d):",w->handle));
  229.     w->rect_user=w->rect_start;
  230.  
  231. #if GENERATE_DIAGS
  232.     if(w->rect_user)
  233.     {
  234.         DIAGS((" [%d,%d,%d,%d]\n",w->rect_user->x,w->rect_user->y,w->rect_user->w,w->rect_user->h));
  235.     }else{
  236.         DIAGS(("***WARNING: rect_get_user_first() with no available list\n"));
  237.     }
  238. #endif
  239.     return w->rect_user;
  240. }
  241.  
  242. XA_RECT_LIST *rect_get_user_next(XA_WINDOW *w)
  243. {
  244.     DIAGS(("get_user_next(%d)\n",w->handle));
  245.     if (w->rect_user)
  246.         w->rect_user=w->rect_user->next;
  247.  
  248. #if GENERATE_DIAGS
  249.     if (w->rect_user)
  250.     {
  251.         DIAGS((" [%d,%d,%d,%d]\n",w->rect_user->x,w->rect_user->y,w->rect_user->w,w->rect_user->h));
  252.     }else{
  253.         DIAGS((" No more rects for %d\n",w->handle));
  254.     }
  255. #endif
  256.     return w->rect_user;
  257. }
  258.  
  259. XA_RECT_LIST *rect_get_system_first(XA_WINDOW *w)
  260. {
  261.     if (!w)
  262.         return NULL;
  263.  
  264.     DIAGS(("get_system_first(%d):",w->handle));
  265.     w->rect_list=w->rect_start;
  266.  
  267. #if GENERATE_DIAGS
  268.     if(w->rect_list)
  269.     {
  270.         DIAGS((" [%d,%d,%d,%d]\n",w->rect_list->x,w->rect_list->y,w->rect_list->w,w->rect_list->h));
  271.     }else{
  272.         DIAGS(("***WARNING: rect_get_system_first() with no available list\n"));
  273.     }
  274. #endif
  275.     return w->rect_list;
  276. }
  277.  
  278. XA_RECT_LIST *rect_get_system_next(XA_WINDOW *w)
  279. {
  280.     if (!w)
  281.         return NULL;
  282.  
  283.     DIAGS(("get_system_next(%d):",w->handle));
  284.     DIAGS(("w->rect_list=%lx\n",w->rect_list));
  285.     DIAGS(("next=%lx\n",w->rect_list->next));
  286.  
  287.     if (w->rect_list)
  288.         w->rect_list=w->rect_list->next;
  289.  
  290. #if GENERATE_DIAGS
  291.     if (w->rect_list)
  292.     {
  293.         DIAGS((" [%d,%d,%d,%d]\n",w->rect_list->x,w->rect_list->y,w->rect_list->w,w->rect_list->h));
  294.     }else{
  295.         DIAGS((" No more rects for %d\n",w->handle));
  296.     }
  297. #endif
  298.  
  299.     return w->rect_list;
  300. }
  301.     
  302.  
  303.